package com.credithc.signature.facade.configure.jdbc;

import com.credithc.signature.common.utils.DateUtil;
import com.google.common.collect.Range;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

@Slf4j
public class DateRangeModuleShardingTableAlgorithm implements RangeShardingAlgorithm<Date> {

    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Date> rangeShardingValue) {
        // 处理日期字段，避免多余查询
        Collection<String> tempCollection = new ArrayList<>();
        tempCollection.addAll(collection);
        List<String> tableName = new ArrayList<>();
        Range<Date> valueRange = rangeShardingValue.getValueRange();
        String logicTableName = rangeShardingValue.getLogicTableName();
        // 起始时间和结束时间都不为空
        if (valueRange.hasLowerBound() && valueRange.hasUpperBound()) {
            Date lowerEndpoint = valueRange.lowerEndpoint();
            Date upperEndpoint = valueRange.upperEndpoint();
            tableName = buildTableName(lowerEndpoint, upperEndpoint, logicTableName);
        }
        // 起始时间不为空
        if (valueRange.hasLowerBound() && !valueRange.hasUpperBound()) {
            Date lowerEndpoint = valueRange.lowerEndpoint();
            tableName = buildTableName(lowerEndpoint, null, logicTableName);
        }
        // 结束时间不为空
        if (valueRange.hasUpperBound() && !valueRange.hasLowerBound()) {
            Date upperEndpoint = valueRange.upperEndpoint();
            tableName = buildTableName(null, upperEndpoint, logicTableName);
        }
        // 过滤表名失败
        if (tableName.isEmpty()) {
            return tempCollection;
        } else {
            tempCollection.retainAll(tableName);
        }
        log.debug("当前SQL语句操作逻辑表为：{}:::表的数量为：{}张表:::{}", logicTableName, tempCollection.size(), tempCollection);
        return tempCollection;
    }

    public static void main(String[] args) {
        Date date = new Date();
        String defaultAppointDateStr = DateUtil.getDefaultAppointDateStr(date);
        log.info(date+"");
        log.info(defaultAppointDateStr);

    }

    /**
     * 获取表名后缀范围
     *
     * @param lowerEndpoint
     * @param upperEndpoint
     * @param logicTableName
     * @return
     */
    public List<String> buildTableName(Date lowerEndpoint, Date upperEndpoint, String logicTableName) {
        List<String> tableSuffixs = new ArrayList<>();
        if (lowerEndpoint != null && upperEndpoint != null) {
            log.debug("请求开始时间:{},请求结束时间:{}", DateUtil.getDefaultAppointDateStr(lowerEndpoint), DateUtil.getDefaultAppointDateStr(upperEndpoint));
            int startMonth = DateUtil.getMonth(lowerEndpoint);
            int endMonth = DateUtil.getMonth(upperEndpoint);
            int startYear = DateUtil.getYear(lowerEndpoint);
            int endYear = DateUtil.getYear(upperEndpoint);
            if (endYear > startYear) {
                endMonth = (endYear - startYear) * 12 + endMonth;
            }
            Date tempDate = lowerEndpoint;
            for (int i = startMonth; i <= endMonth; i++) {
                String yearAndMonth = DateUtil.getYearAndMonth(tempDate);
                tableSuffixs.add(logicTableName + "_" + yearAndMonth);
                Date nextMonth = DateUtil.getNextMonth(tempDate);
                tempDate = nextMonth;
            }
        } else if (lowerEndpoint != null && upperEndpoint == null) {
            // 起始时间不为空
            String currentYearAndMonth = DateUtil.getYearAndMonth(lowerEndpoint);
            tableSuffixs.add(logicTableName + "_" + currentYearAndMonth);
        } else if (lowerEndpoint == null && upperEndpoint != null) {
            // 结束时间不为空
            String currentYearAndMonth = DateUtil.getYearAndMonth(upperEndpoint);
            tableSuffixs.add(logicTableName + "_" + currentYearAndMonth);
        }
        return tableSuffixs;
    }
}
